<?php

namespace app\models;

use Yii;
use yii\base\Exception;
use yii\base\Model;

/**
 * 导入卡表单
 * Class CardImportForm
 * @package app\models
 */
class CardImportForm extends Model
{
    /**
     * @var integer 接口编号
     */
    public $api_id;
    /**
     * @var integer 运营商编号
     */
    public $isp_id;
    /**
     * @var string ICCID列表
     */
    public $iccid_list;
    /**
     * @var string ICCID开始号码
     */
    public $iccid_start;
    /**
     * @var string ICCID结束号码
     */
    public $iccid_end;
    /**
     * @var string 批次号
     */
    public $batch_no;

    public $package_id;
    /**
     * @inheritdoc
     */
    public function rules()
    {
        return [
            ['iccid_list', 'safe'],
            [['iccid_start', 'iccid_end'], 'safe'],
            [['api_id', 'isp_id'], 'required'],
            ['package_id','safe'],
            ['api_id', 'exist', 'targetClass' => Api::class, 'targetAttribute' => 'id'],
            ['isp_id', 'exist', 'targetClass' => Isp::class, 'targetAttribute' => 'id'],
            ['batch_no', 'string', 'max' => 32],
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'api_id' => '接口',
            'isp_id' => '运营商',
            'package_id' => '套餐',
            'iccid_list' => 'ICCID列表',
            'iccid_start' => 'ICCID开始号码',
            'iccid_end' => 'ICCID结束号码',
            'batch_no' => '批次号',
        ];
    }

    /**
     * 导入操作
     * @param integer $mid 管理员编号
     * @return bool
     */
    public function import($mid = 0)
    {
        if (!$this->validate()) {
            return false;
        }
        $iccidList = [];
        if (!empty($this->iccid_start) || !empty($this->iccid_end)) {
            if (empty($this->iccid_start)) {
                $this->addError('iccid_start', 'ICCID开始号码必须填写。');
                return false;
            }
            if (empty($this->iccid_end)) {
                $this->addError('iccid_end', 'ICCID结束号码必须填写。');
                return false;
            }
            if (strlen($this->iccid_start) != strlen($this->iccid_end)) {
                $this->addError('iccid_end', 'ICCID开始号码和结束号码长度不一致。');
                return false;
            }
            // 生成ICCID列表
            for ($i = 0; $i < strlen($this->iccid_start); $i++) {
                if ($this->iccid_start[$i] != $this->iccid_end[$i]) {
                    $prefix = substr($this->iccid_start, 0, $i);
                    $iccidList = range(substr($this->iccid_start, $i), substr($this->iccid_end, $i));
                    $chrLen = strlen(substr($this->iccid_start, $i));
                    array_walk($iccidList, function (&$item) use ($prefix, $chrLen) {
                        $item = $prefix . str_pad($item, $chrLen, '0', STR_PAD_LEFT);
                    });
                    break;
                }
            }
        } else {
            if (empty($this->iccid_list)) {
                $this->addError('iccid_list', 'ICCID列表必须填写。');
                return false;
            }
            $iccidList = preg_split('/\s/', $this->iccid_list, -1, PREG_SPLIT_NO_EMPTY);
        }
        if (empty($iccidList)) {
            $this->addError('iccid_list', '没有找到任何有效卡号。');
            return false;
        }
        $trans = Yii::$app->db->beginTransaction();
        if (empty($this->batch_no)) {
            $this->batch_no = Card::generateBatchNo($mid);
        }
        try {
            foreach ($iccidList as $iccid) {
                if (Card::find()->andWhere(['iccid' => $iccid])->exists()) {
                    throw new Exception('【' . $iccid . '】已经存在了。');
                }
                $card = new Card();
                $card->api_id = $this->api_id;
                $card->isp_id = $this->isp_id;
                $card->iccid = $iccid;
                $card->package_id = $this->package_id;
                $card->status = Card::STATUS_TEST_READY;
                $card->batch_no = $this->batch_no;
                $card->create_time = time();
                $card->save();
            }
            $trans->commit();

            return true;
        } catch (Exception $e) {
            try {
                $trans->rollBack();
            } catch (Exception $_) {
            }
            $this->addError('iccid_list', $e->getMessage());
            return false;
        }
    }
}